abstract class AbstractCustomer {
    protected name: string = '';
    public abstract isNull(): boolean;
    public abstract getName(): string;
}

class RealCustomer extends AbstractCustomer {
    public constructor(name: string) {
        super();
        this.name = name;
    }
    public override isNull(): boolean {
        return false;
    }
    public override getName(): string {
        return this.name;
    }
}

class NullCustomer extends AbstractCustomer {
    private static instance: NullCustomer = new NullCustomer();
    private constructor() {
        super();
    }
    public static getInstance(): NullCustomer {
        return this.instance;
    }
    public override isNull(): boolean {
        return true;
    }
    public override getName(): string {
        return 'Not Available';
    }
}

class CustomerFactory {
    public static readonly names: string[] = ["Alice", "Bob", "Charlie", "David", "Emily", "Frank", "Grace"];
    public static getCustomer(name: string): AbstractCustomer {
        if (this.names.includes(name)) {
            return new RealCustomer(name);
        }
        return NullCustomer.getInstance();
    }
}

function main() {
    const customer1: AbstractCustomer = CustomerFactory.getCustomer("Alice");
    console.log(customer1.getName()); // Alice
    console.log(customer1.isNull()); // false
    const customer2: AbstractCustomer = CustomerFactory.getCustomer("Tom");
    console.log(customer2.getName()); // Not Available
    console.log(customer2.isNull()); // true
}

main();
